package com.rykj.energy.task.message.construct;

import com.alibaba.fastjson.JSONObject;
import com.rykj.energy.common.enums.BusinessType;
import com.rykj.energy.common.utils.CollectionUtils;
import com.rykj.energy.common.utils.HttpClientUtils;
import com.rykj.energy.common.utils.RedisUtil;
import com.rykj.energy.common.utils.StringUtils;
import com.rykj.energy.database.pojo.BasicCamera;
import com.rykj.energy.database.pojo.MessageResult;
import com.rykj.energy.database.pojo.TaskCameraRelation;
import com.rykj.energy.database.pojo.TaskInfo;
import com.rykj.energy.database.pojo.vo.TaskSyncParam;
import com.rykj.energy.database.service.ICameraService;
import com.rykj.energy.database.service.IMeterService;
import com.rykj.energy.database.service.IMsgResultService;
import com.rykj.energy.database.service.ITaskInfoService;
import com.rykj.energy.task.message.service.IMsgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Component
public class ConstructStartup implements ApplicationRunner {

    public static String CACH_CAPTURE_IMG_KEY = "cach_capture_img_key";

    public static String ADC_SYNC_TASK="/adc/sync/task";
    //温度识别接口
    private static String GET_TEMPERATURE="/adc/sync/camera/getTemperature";

    @Autowired
    private IMsgResultService msgResultService;

    @Autowired
    private IMeterService meterService;

    @Resource
    private RedisUtil redisUtil;

    @Autowired
    private ITaskInfoService taskInfoService;

    @Autowired
    private ICameraService cameraService;

    @Autowired
    private IMsgService msgService;

    @Value("${check.msg.threadNum:2}")
    private Integer checkTheadNum;


    //@Value("${img.map.url}")
   // private String imgMapUrl;

    @Value("${cluster.http.ip:http://127.0.0.1:7771}")
    private String clusterHttpIp;

    @Value("${cluster.http.temperature:http://10.152.44.31:7771}")
     private String temperatureHttp;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        init();
    }

    public  void init(){
        String mobj =null;
        ExecutorService executor = Executors.newFixedThreadPool(checkTheadNum);
        while (true) {
                try {
                    mobj= (String) redisUtil.lRightPop(CACH_CAPTURE_IMG_KEY);
                    if(StringUtils.isEmpty(mobj)) {
                        Thread.sleep(5000);
                        continue;
                    }
                    log.info("====redis中的仪表信息=="+mobj);
                    executor.submit(new CheckMeterAble(mobj,checkTheadNum));
                } catch (InterruptedException e) {
                    log.error("==仪表检测结果分析异常==",e);
                }
            }
        }

    /**
     * 线程池执行任务
     */
    public class CheckMeterAble implements Callable<Integer> {
        private String mobj ;
        private int n;
        public CheckMeterAble(String mobj,Integer n){
            this.mobj=mobj;
            this.n=n;
        }
        @Override
        public Integer call() {
            try {
                JSONObject  result= JSONObject.parseObject(mobj);
                Integer  resultId =  Integer.valueOf(result.get("resultId")+"");
                MessageResult msgResult= msgResultService.selectById(resultId);
                if(null==msgResult){
                    return n;
                }
                TaskSyncParam syncParam = new TaskSyncParam();
                syncParam.setType(msgResult.getMsgType());
                if("switchs".equals(msgResult.getMsgType())){
                    syncParam.setType("switch");
                }
                syncParam.setContent(msgResult.getImageUrl());
                TaskInfo taskInfo =taskInfoService.findByCode(msgResult.getMsgType());
                //通用配置的默认最大值，最小值
                JSONObject businessCont= new JSONObject();
                if(StringUtils.isNotEmpty(taskInfo.getBusinessContent())){
                    businessCont= JSONObject.parseObject(taskInfo.getBusinessContent());
                }
                if(StringUtils.isNotEmpty(businessCont.get("maxVal"))){
                    syncParam.setMaxVal(businessCont.getString("maxVal"));
                }
                if(StringUtils.isNotEmpty(businessCont.get("minVal"))){
                    syncParam.setMinVal(businessCont.getString("minVal"));
                }
                TaskCameraRelation cameraRelat=taskInfoService.findByTaskIdAndCameraIdAndPreseId(msgResult.getTaskId(),msgResult.getCameraId(),msgResult.getPresetId());
                if(StringUtils.isNotEmpty(cameraRelat.getBusinessContent())){
                    businessCont= JSONObject.parseObject(cameraRelat.getBusinessContent());
                }
                //摄像头独立配置的最大值，最小值
                List<Map<String,Object>> alarmValues = meterService.getAlarmValues(msgResult.getTaskId(),msgResult.getCameraId());
                getAralmValues(syncParam,alarmValues);
//                if(StringUtils.isNotEmpty(businessCont.get("maxVal"))){
//                    syncParam.setMaxVal(businessCont.getString("maxVal"));
//                }
//                if(StringUtils.isNotEmpty(businessCont.get("minVal"))){
//                    syncParam.setMinVal(businessCont.getString("minVal"));
//                }
                if(StringUtils.isNotEmpty(businessCont.get("areas"))){
                    syncParam.setAreas(businessCont.getString("areas"));
                    msgResult.setAreaFrame(syncParam.getAreas());
                }
                log.info("===图片检测=调用计算端传递参数为=====：" + JSONObject.toJSONString(syncParam));
                String retStr = "";

                if(BusinessType.wdjc.getbType().equals(taskInfo.getTaskCode())){
                    BasicCamera camera =cameraService.findById(msgResult.getCameraId());
                    String tmpUrl=temperatureHttp+GET_TEMPERATURE+"?ip="+camera.getCamIp()+"&port="+camera.getCamPort()+"&username="+camera.getCamUser()+"&pwd="+camera.getCamPwd()+"&type="+
                            camera.getCamBrands()+"&channel="+1+"&areas="+syncParam.getAreas();
                    log.info("===温度检测请求url===="+tmpUrl);
                    retStr = HttpClientUtils.get(tmpUrl);
                }else {
                    retStr = HttpClientUtils.postStr(clusterHttpIp + ADC_SYNC_TASK, JSONObject.toJSONString(syncParam));

                }
                log.info("====图片检测结果为=====：" + retStr);
                if (StringUtils.isEmpty(retStr)) {
                    log.error("===resultId=="+resultId+"==未检测到数据，请重新调整角度，或检测类型不匹配");
                    return 0;
                }
                JSONObject jsonObject = JSONObject.parseObject(retStr);
                if("0".equals(jsonObject.getString("code"))){
                    log.error("====检测结果code=0,检测结果失败==msg=="+jsonObject.getString("msg"));
                    return 0;
                }
                msgResult.setRemark(StringUtils.replaceBlank(retStr));
                msgService.dealCapturMsg(msgResult,jsonObject,alarmValues,businessCont);
            }catch (Exception e){
                log.error("仪表检测运行异常",e);
            }catch (Error r){
                log.error("=====仪表检测错误===",r);
            }
            return n;
        }
    }

    private void getAralmValues( TaskSyncParam syncParam, List<Map<String,Object>> alarmValues){
        if(CollectionUtils.isNotEmpty(alarmValues)){
            List<Float> minVals=new ArrayList<>();
            List<Float> maxVals=new ArrayList<>();
            for (Map<String,Object> alarmValue:alarmValues) {
                if(StringUtils.isNotEmpty(alarmValue.get("minVal"))){
                    minVals.add(Float.valueOf(alarmValue.get("minVal")+""));
                }
                if(StringUtils.isNotEmpty(alarmValue.get("maxVal"))){
                    maxVals.add(Float.valueOf(alarmValue.get("maxVal")+""));
                }
            }
            syncParam.setMaxVal(JSONObject.toJSONString(maxVals));
            syncParam.setMinVal(JSONObject.toJSONString(minVals));
        }

    }

}
